package org.wang.gift.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.wang.gift.clients.LoginUserClient;
import org.wang.gift.constans.BaseConstans;
import org.wang.gift.domain.Employee;
import org.wang.gift.domain.LoginUser;
import org.wang.gift.domain.Tenant;
import org.wang.gift.dto.TenantEnterDto;
import org.wang.gift.exception.BusinessException;
import org.wang.gift.exception.asserts.Assert;
import org.wang.gift.exception.code.StatusCode;
import org.wang.gift.mapper.EmployeeMapper;
import org.wang.gift.mapper.TenantMapper;
import org.wang.gift.query.TenantQuery;
import org.wang.gift.service.ITenantService;
import org.wang.gift.util.AjaxResult;
import org.wang.gift.util.PageList;

import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author wangsang
 * @since 2022-10-09
 */
@Service
public class TenantServiceImpl extends ServiceImpl<TenantMapper, Tenant> implements ITenantService {
    @Autowired
    private TenantMapper tenantMapper;
    @Autowired
    private EmployeeMapper employeeMapper;

    @Autowired
    private LoginUserClient loginUserClient;


    @Override
    public Object selectPageList(TenantQuery query) {
        Page<Tenant> page = new Page<>(query.getPage(),query.getRows());//分页条件
        List<Tenant> rows = tenantMapper.selectPageList(page,query);
        return new PageList<Tenant>(page.getTotal(), rows);
    }



    @Override
    @Transactional
    public AjaxResult settlement(TenantEnterDto tenantEnterDto) {
        try {
            //1 校验数据
            validate(tenantEnterDto);
            //2 保存数据  店铺 店铺管理员 登陆信息  用户套餐中间表
            //2.1 保存登陆信息及用户套餐中间表并发返回loginId-->其他服务的功能（openfegin） loginUser+mealId=Map/Dto
            //方案1：谁提供服务谁写 好处：能直接用它的公共代码,坏处就是要让别人写接口---一个团队甚至一个人
            //方案2：更加接口文档自己来写  好处：没有任何耦合，坏处：有重复dto----如果两个团队分别写服务
            //设置登录用户信息
            AjaxResult ajaxResultByLoginUser = insertLoginUser(tenantEnterDto);
            Object objByLoginUser = ajaxResultByLoginUser.getResultObj();
            Long loginUserId = Long.valueOf(String.valueOf(objByLoginUser));
            //2.2  店铺管理员
            AjaxResult ajaxResultByEmployee = insertEmployee(tenantEnterDto, loginUserId);
            if (!ajaxResultByEmployee.isSuccess()){
                //抛出异常
                throw new RuntimeException("用户保存失败");
            }
            Object objByEmployee = ajaxResultByEmployee.getResultObj();
            Long adminId = Long.valueOf(String.valueOf(objByEmployee));
            //2.3 店铺信息
            AjaxResult ajaxResultByTenant = insertTenant(tenantEnterDto, adminId);
            if (!ajaxResultByTenant.isSuccess()){
                //抛出异常
                throw new RuntimeException("用户保存失败");
            }
            Object objByTenant = ajaxResultByTenant.getResultObj();
            Long tenantId = Long.valueOf(String.valueOf(objByTenant));
            employeeMapper.updateTenantId(tenantId,adminId);
            Long mealId = tenantEnterDto.getMealId();
            tenantMapper.insertMealAndTenant(tenantId,mealId);
            return AjaxResult.me();
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.me().setSuccess(false).setMessage(e.getMessage());
        }

    }

    /**
     * 添加租户
     * @param tenantEnterDto
     * @param adminId
     * @return
     */
    @Transactional
    public AjaxResult insertTenant(TenantEnterDto tenantEnterDto,Long adminId){
        Tenant tenant = tenantEnterDto.getTenant();
        tenant.setAdminId(adminId);
        tenant.setState(BaseConstans.Tanent.STATE_WAIT_AUTID);
        tenant.setRegisterTime(new Date());
        tenantMapper.insert(tenant);
        Long id = tenant.getId();
        return AjaxResult.me().setResultObj(id);
    }

    /**
     * 添加用户
     * @param tenantEnterDto
     * @param loginId
     * @return
     */
    @Transactional
    public AjaxResult insertEmployee(TenantEnterDto tenantEnterDto,Long loginId){
        Employee admin = tenantEnterDto.getAdmin();
        admin.setInputTime(new Date());
        admin.setLoginId(loginId);
        employeeMapper.insert(admin);
        Long id = admin.getId();
        return AjaxResult.me().setResultObj(id);
    }

    /**
     * 添加登录用户
     * @param tenantEnterDto
     * @return
     */
    @Transactional
    public AjaxResult insertLoginUser(TenantEnterDto tenantEnterDto) {
        Employee admin = tenantEnterDto.getAdmin();
        LoginUser loginUser = new LoginUser();
        loginUser.setUsername(admin.getUsername());
        loginUser.setPassword(admin.getPassword());
        loginUser.setTel(admin.getTel());
        loginUser.setEmail(admin.getEmail());
        loginUser.setType(BaseConstans.LoginUser.TYPE_ADMIN);
        //保存LoginUser
        AjaxResult ajaxResult = loginUserClient.addOrUpdate(loginUser);
        if (!ajaxResult.isSuccess()){
            //抛出异常
            throw new RuntimeException("登录用户保存失败");
        }
        return ajaxResult;
    }

    /**
     * 参数校验
     * @param tenantEnterDto
     */
    private void validate(TenantEnterDto tenantEnterDto) {
        //1参数校验
        //1.1 null校验
        Employee admin = tenantEnterDto.getAdmin();
        Tenant tenant = tenantEnterDto.getTenant();
        //两次密码比对
        Assert.assertEquals(admin.getPassword(), admin.getComfirmPassword(), StatusCode.CODE_400_PASSWORD);

        //1.2 店铺是否存在校验
        List<Tenant> tenants = tenantMapper.selectList(new EntityWrapper<Tenant>().eq("company_name", tenant.getCompanyName()));
        Assert.assertListIsEmpty(tenants,StatusCode.CODE_400_TENANT_EXSIT);
        //1.3 管理员存在校验
        List<Employee> employees = employeeMapper.selectList(new EntityWrapper<Employee>().eq("username",admin.getUsername()));
        Assert.assertListIsEmpty(employees,StatusCode.CODE_400_TENANT_ADMIN_EXSIT);
    }


    //    /**
//     * 参数校验
//     * @param tenantEnterDto
//     */
//    private void validate(TenantEnterDto tenantEnterDto) {
//        //1参数校验
//        //1.1 null校验
//        Employee admin = tenantEnterDto.getAdmin();
//        Tenant tenant = tenantEnterDto.getTenant();
//        Long mealId = tenantEnterDto.getMealId();
//        //用户信息校验
//        Assert.assertNotNull(admin,"系统错误！请输入相关信息后再操作");
//        Assert.assertNotEmpty(admin.getUsername(),"系统错误！请输入相关信息后再操作");
//        Assert.assertNotEmpty(admin.getPassword(),"系统错误！请输入相关信息后再操作");
//        Assert.assertNotEmpty(admin.getComfirmPassword(),"系统错误！请输入相关信息后再操作");
//        //两次密码比对
//        Assert.assertEquals(admin.getPassword(), admin.getComfirmPassword(), "两次密码不一致");
//        //租户信息校验
//        Assert.assertNotNull(tenant,"系统错误！请输入相关信息后再操作");
//        Assert.assertNotEmpty(tenant.getCompanyName(),"系统错误！请输入相关信息后再操作");
//        Assert.assertNotEmpty(tenant.getCompanyNum(),"系统错误！请输入相关信息后再操作");
//        Assert.assertNotEmpty(tenant.getAddress(),"系统错误！请输入相关信息后再操作");
//        //套餐校验
//        Assert.assertNotNull(mealId,"系统错误！请输入相关信息后再操作");
//
//        //1.2 店铺是否存在校验
//        List<Tenant> tenants = tenantMapper.selectList(new EntityWrapper<Tenant>().eq("company_name", tenant.getCompanyName()));
//        Assert.assertListIsEmpty(tenants,"该店铺已经存在！");
//        //1.3 管理员存在校验
//        List<Employee> employees = employeeMapper.selectList(new EntityWrapper<Employee>().eq("username",admin.getUsername()));
//        Assert.assertListIsEmpty(employees,"请登录，在后台添加租户提交审核！");
//    }


    //    /**
//     * 参数校验
//     * @param tenantEnterDto
//     */
//    private void validate(TenantEnterDto tenantEnterDto) {
//        //1参数校验
//        //1.1 null校验
//        Employee admin = tenantEnterDto.getAdmin();
//        Tenant tenant = tenantEnterDto.getTenant();
//        Long mealId = tenantEnterDto.getMealId();
//        //用户信息校验
//        if(admin == null)
//            throw new BusinessException("系统错误！请输入相关信息后再操作");
//        if(StringUtils.isEmpty(admin.getUsername()) || StringUtils.isEmpty(admin.getPassword()) || StringUtils.isEmpty(admin.getComfirmPassword()))
//            throw new BusinessException("系统错误！请输入相关信息后再操作");
//        //租户信息校验
//        if(tenant == null)
//            throw new BusinessException("系统错误！请输入相关信息后再操作");
//        if (StringUtils.isEmpty(tenant.getCompanyName()) || StringUtils.isEmpty(tenant.getAddress()))
//            throw new BusinessException("系统错误！请输入相关信息后再操作");
//        //套餐校验
//        if(mealId == null)
//            throw new BusinessException("系统错误！请输入相关信息后再操作");
//
//        //两次密码比对
//        if (!admin.getPassword().trim().equals(admin.getComfirmPassword().trim()))
//            throw new BusinessException("两次密码不一致");
//        //1.2 店铺是否存在校验
//        Tenant tenantByDb = tenantMapper.selectByCompanyName(tenant.getCompanyName());
//        if (tenantByDb != null)
//            throw new BusinessException("该店铺已经存在！");
//        //1.3 管理员存在校验
//        Employee employeeByDb = employeeMapper.selectByUsername(admin.getUsername());
//        if (employeeByDb != null)
//            throw new BusinessException("请登录，在后台添加租户提交审核！");
//    }



    //    /**
//     * 参数校验
//     * @param tenantEnterDto
//     */
//    private void validate(TenantEnterDto tenantEnterDto) {
//        //1参数校验
//        //1.1 null校验
//        Employee admin = tenantEnterDto.getAdmin();
//        Tenant tenant = tenantEnterDto.getTenant();
//        Long mealId = tenantEnterDto.getMealId();
//        //用户信息校验
//        if(admin == null)
//            throw new RuntimeException("系统错误！请输入相关信息后再操作");
//        if(StringUtils.isEmpty(admin.getUsername()) || StringUtils.isEmpty(admin.getPassword()) || StringUtils.isEmpty(admin.getComfirmPassword()))
//            throw new RuntimeException("系统错误！请输入相关信息后再操作");
//        //租户信息校验
//        if(tenant == null)
//            throw new RuntimeException("系统错误！请输入相关信息后再操作");
//        if (StringUtils.isEmpty(tenant.getCompanyName()) || StringUtils.isEmpty(tenant.getAddress()))
//            throw new RuntimeException("系统错误！请输入相关信息后再操作");
//        //套餐校验
//        if(mealId == null)
//            throw new RuntimeException("系统错误！请输入相关信息后再操作");
//
//        //两次密码比对
//        if (!admin.getPassword().trim().equals(admin.getComfirmPassword().trim()))
//            throw new RuntimeException("两次密码不一致");
//        //1.2 店铺是否存在校验
//        Tenant tenantByDb = tenantMapper.selectByCompanyName(tenant.getCompanyName());
//        if (tenantByDb != null)
//            throw new RuntimeException("该店铺已经存在！");
//        //1.3 管理员存在校验
//        Employee employeeByDb = employeeMapper.selectByUsername(admin.getUsername());
//        if (employeeByDb != null)
//            throw new RuntimeException("请登录，在后台添加租户提交审核！");
//    }
}
